<?php
/**
 * Created by PhpStorm.
 * User: cnpscy
 * Date: 2020/7/7
 * Time: 22:56
 * Note: Base.php
 */

namespace App\Base;

use EasySwoole\EasySwoole\Config;
use EasySwoole\EasySwoole\ServerManager;
use EasySwoole\Http\AbstractInterface\Controller;
use EasySwoole\Http\Message\Status;
use EasySwoole\Http\Request;
use EasySwoole\Http\Response;

class BaseController extends Controller
{
    public function __hook(?string $actionName, Request $request, Response $response, callable $actionHook = null)
    {
        if (method_exists($this, 'beforeAction')) $this->beforeAction($actionName, $request);
        parent::__hook($actionName, $request, $response, $actionHook);
    }

    /**
     * 获取用户的真实IP
     *
     * @param string $headerName 代理服务器传递的标头名称
     *
     * @return string
     */
    public function clientRealIP($headerName = 'x-real-ip')
    {
        $server        = ServerManager::getInstance()->getSwooleServer();
        $client        = $server->getClientInfo($this->request()->getSwooleRequest()->fd);
        $clientAddress = $client['remote_ip'];
        $xri           = $this->request()->getHeader($headerName);
        $xff           = $this->request()->getHeader('x-forwarded-for');
        if ($clientAddress === '127.0.0.1') {
            if (!empty($xri)) {  // 如果有xri 则判定为前端有NGINX等代理
                $clientAddress = $xri[0];
            } elseif (!empty($xff)) {  // 如果不存在xri 则继续判断xff
                $list = explode(',', $xff[0]);
                if (isset($list[0])) $clientAddress = $list[0];
            }
        }
        return $clientAddress;
    }

    public function onRequest(?string $action): ?bool
    {
        if (!parent::onRequest($action)) {
            return false;
        };
        return true;
    }

    protected function actionNotFound(?string $action)
    {
        parent::actionNotFound($action); // TODO: Change the autogenerated stub
    }

    /**
     * 获取配置值
     *
     * @param      $name
     * @param null $default
     *
     * @return array|mixed|null
     */
    function cfgValue($name, $default = null)
    {
        $value = Config::getInstance()->getConf($name);
        return is_null($value) ? $default : $value;
    }

    protected function successJson($data = [], $status = 1, $msg = '成功', $small_tips = '')
    {
        return $this->myJson(['data' => $data, 'status' => $status, 'msg' => $msg, 'small_tips' => $small_tips]);
    }

    protected function errorJson($msg, $status = 0, $small_tips = '')
    {
        return $this->myJson(['status' => $status, 'msg' => $msg, 'small_tips' => $small_tips]);
    }

    protected function myJson($data, array $extends_info = [])
    {
        $status     = isset($data['status']) ? $data['status'] : Status::CODE_OK;
        $msg        = isset($data['msg']) ? $data['msg'] : Status::getReasonPhrase($status);
        $data       = isset($data['data']) ? $data['data'] : [];
        $small_tips = isset($data['small_tips']) ? $data['small_tips'] : '';
        return $this->writeJson($status, $data, $msg, $small_tips, $extends_info);
    }

    protected function writeJson($statusCode = 200, $result = [], $msg = '', $small_tips = '', array $extends_info = [])
    {
        if (!$this->response()->isEndResponse()) {
            $data = [
                'code'       => $statusCode,
                'data'       => $result,
                'msg'        => $msg,
                'small_tips' => $small_tips
            ];
            $data = array_merge($data, $extends_info);
            $this->response()->write(json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
            $this->response()->withHeader('Content-type', 'application/json;charset=utf-8');
            $this->response()->withStatus($statusCode);
            return true;
        } else {
            return false;
        }
    }
}